package com.winning.devops.batch.reader.ch06.config;

import com.winning.devops.batch.reader.ch06.domain.Customer;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.MultiResourceItemReader;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.mapping.FieldSetMapper;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.batch.item.file.transform.FieldSet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.validation.BindException;

/**
 * 从多个文件中读取数据
 * <p>
 * 多个文件为 resources目录下 t1~t3.txt三个文件
 *
 * @author chensj
 * @date 2020-03-04 21:00
 */
@Configuration
public class MultiFilesJobDemoConfig {
    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;
    @Value("classpath:t*.txt")
    private Resource[] fileResources;
    @Autowired
    @Qualifier("flatFileItemWriter")
    private ItemWriter<? super Customer> flatFileItemWriter;


    @Bean
    public Job multiFilesJobDemoJob() {
        return jobBuilderFactory.get("multiFilesJobDemoJob")
                .start(multiFilesJobDemoStep())
                .build();
    }

    @Bean
    public Step multiFilesJobDemoStep() {
        return stepBuilderFactory
                .get("multiFilesJobDemoStep")
                .<Customer, Customer>chunk(10)
                .reader(multiFilesJobDemoReader())
                .writer(flatFileItemWriter)
                .build();

    }

    @Bean
    @StepScope
    public MultiResourceItemReader<Customer> multiFilesJobDemoReader() {
        MultiResourceItemReader<Customer> reader = new MultiResourceItemReader<>();
        // 指定代理类 来实现单文件读取功能
        reader.setDelegate(flatFileItemReader());
        // 指定读取资源
        reader.setResources(fileResources);
        return reader;
    }

    @Bean
    @StepScope
    public FlatFileItemReader<Customer> flatFileItemReader() {
        FlatFileItemReader<Customer> reader = new FlatFileItemReader<>();
        // 设置读取文件位置
        reader.setResource(new ClassPathResource("test.txt"));
        // 跳过第几行
        reader.setLinesToSkip(1);
        // 数据解析
        DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer();
        tokenizer.setNames(new String[]{"id", "firstName", "lastName", "birthday"});
        // 映射到实体类
        DefaultLineMapper<Customer> mapper = new DefaultLineMapper<>();
        mapper.setLineTokenizer(tokenizer);
        mapper.setFieldSetMapper(new FieldSetMapper<Customer>() {
            @Override
            public Customer mapFieldSet(FieldSet fieldSet) throws BindException {
                Customer customer = new Customer();
                customer.setId(fieldSet.readInt("id"));
                customer.setFirstName(fieldSet.readString("firstName"));
                customer.setLastName(fieldSet.readString("lastName"));
                customer.setBirthday(fieldSet.readString("birthday"));
                return customer;
            }
        });
        // 检查参数
        mapper.afterPropertiesSet();
        reader.setLineMapper(mapper);

        return reader;
    }

}
